﻿// *********************************************************************
// [DCOM Productions]
// [Copyright (C) DCOM Productions All rights reserved.]
// *********************************************************************

namespace BitFlex.Windows.Forms {
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Security.Permissions;
    using System.Runtime.InteropServices;
    using System.Diagnostics;

    /// <summary>
    /// The Windows Vista CommandLink
    /// </summary>
    [ToolboxBitmap(typeof(Button))]
    public sealed partial class CommandLink : System.Windows.Forms.Button {
        /// <summary>
        /// Instantiates a new instance of the BitFlex.Windows.Forms.CommandLink class
        /// </summary>
        public CommandLink() {
            InitializeComponent();

            if (IsWindowsVista()) {
                FlatStyle = FlatStyle.System;
            }
        }

        #region Platform Invoke

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam);

        #endregion

        #region Constants

        private const Int32 BCM_SETNOTE = 0x00001609;
        private const Int32 BCM_SETSHIELD = 0x0000160C;
        private const Int32 BM_SETIMAGE = 0x00F7;
        private const Int32 BS_COMMANDLINK = 0x0000000E;

        #endregion

        /// <summary>
        /// Encapsulates the information needed when creating a control
        /// </summary>
        protected override CreateParams CreateParams {
            [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] get {
                if (IsWindowsVista()) {
                    CreateParams cp = base.CreateParams;
                    cp.Style |= BS_COMMANDLINK;
                    return cp;
                }
                else {
                    return base.CreateParams;
                }
            }
        }

        #region Properties

        private Bitmap m_Image;
        /// <summary>
        /// Gets or Sets the display image
        /// </summary>
        [
            Category("Appearance"),
            Description("Gets or Sets the display image")
        ]
        new public Bitmap Image {
            get {
                if (IsWindowsVista()) {
                    return m_Image;
                }
                else {
                    return (Bitmap)base.Image;
                }
            }
            set {
                if (IsWindowsVista()) {
                    UseShield = false;
                    m_Image = value;
                    SetImage();
                }
                else {
                    base.Image = (Image)value;
                }
            }
        }

        private String m_Note = String.Empty;
        /// <summary>
        /// Gets or Sets the CommandLink's note
        /// </summary>
        [
            Category("Appearance"),
            DefaultValue(""),
            Description("Gets or Sets the CommandLink's note")
        ]
        public String Note {
            get {
                return m_Note;
            }
            set {
                m_Note = value;

                if (IsWindowsVista()) {
                    SetNote();
                }
                else {
                    Debug.Assert(false, "The CommandLink control is not supported on operating systems earlier than Windows Vista.");
                }
            }
        }

        private Boolean m_UseShield;
        /// <summary>
        /// Gets or Sets a value indicating whether the Shield Icon is displayed
        /// </summary>
        [
            Category("Appearance"),
            DefaultValue(false),
            Description("Gets or Sets a value indicating whether the Shield Icon is displayed")
        ]
        public Boolean UseShield {
            get {
                return m_UseShield;
            }
            set {
                m_UseShield = value;

                if (IsWindowsVista()) {
                    SetShield();
                }
                else {
                    Debug.Assert(false, "The CommandLink control is not supported on operating systems earlier than Windows Vista.");
                }
            }
        }

        #endregion

        #region Methods

        private static Boolean IsWindowsVista() {
            if (Environment.OSVersion.Version.Major >= 6) {
                return true;
            }
            else {
                return false;
            }
        }

        private void SetImage() {
            if (Image == null) {
                SendMessage(Handle, BM_SETIMAGE, new IntPtr(1), IntPtr.Zero);
            }
            else {
                SendMessage(Handle, BM_SETIMAGE, new IntPtr(1), Image.GetHicon());
            }
        }

        private void SetNote() {
            SendMessage(Handle, BCM_SETNOTE, IntPtr.Zero, Marshal.StringToBSTR(Note));
        }

        private void SetShield() {
            if (UseShield) {
                SendMessage(Handle, BCM_SETSHIELD, IntPtr.Zero, new IntPtr(UseShield ? 1 : 0));
            }
            else {
                SetImage();
            }
        }

        #endregion
    }
}